package top.dbhg.tasklist.hud;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.Formatting;
import net.minecraft.world.PersistentState;
import net.minecraft.world.PersistentStateManager;
import net.minecraft.world.World;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.CopyOnWriteArrayList;

import static top.dbhg.tasklist.Tasklist.MOD_ID;

public class TaskState extends PersistentState {
    private static final Gson GSON = new Gson();
    private static final String KEY = MOD_ID;

    private final CopyOnWriteArrayList<Task> tasks;

    public TaskState() {
        this.tasks = new CopyOnWriteArrayList<>();
    }

    public static TaskState fromNbt(NbtCompound nbt) {
        TaskState state = new TaskState();
        String json = nbt.getString(KEY);
        List<Task> loadedTasks = GSON.fromJson(json, new TypeToken<List<Task>>(){}.getType());
        state.tasks.addAll(loadedTasks);
        return state;
    }

    public static TaskState getServerState(MinecraftServer server) {
        PersistentStateManager persistentStateManager = Objects.requireNonNull(server.getWorld(World.OVERWORLD)).getPersistentStateManager();
        TaskState state = persistentStateManager.getOrCreate(type, MOD_ID);
        state.markDirty();
        return state;
    }

    public static Type<TaskState> type = new Type<>(
            TaskState::new, // 若不存在 'StateSaverAndLoader' 则创建
            TaskState::fromNbt, // 若存在 'StateSaverAndLoader' NBT, 则调用 'createFromNbt' 传入参数
            null // 此处理论上应为 'DataFixTypes' 的枚举，但我们直接传递为空(null)也可以
    );

    @Override
    public NbtCompound writeNbt(NbtCompound nbt) {
        String json = GSON.toJson(tasks);
        nbt.putString(KEY, json);
        return nbt;
    }

    public CopyOnWriteArrayList<Task> getTasks() {
        return tasks;
    }

    public void addTask(Task task) {
        tasks.add(task);
        markDirty();  // 标记数据为脏数据，使其在下次保存时写入磁盘
    }

    public void removeTask(String tag) {
        tasks.removeIf(task -> task.tag.equals(tag));
        markDirty();
    }

    public static class Task {
        String tag;
        String text;
        Formatting color;
        int animationX;
        boolean visible;

        Task(String tag, String text, Formatting color) {
            this.tag = tag;
            this.text = text;
            this.color = color;
            this.animationX = -200; // 初始位置在屏幕外
            this.visible = true;
        }
    }
}